﻿using CK.Sprite.Form.Core;
using CK.Sprite.Framework;
using Dapper;
using Dapper.Contrib.Extensions;
using JetBrains.Annotations;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;

namespace CK.Sprite.Form.MySql
{
    public class SpriteFormRepository : BaseSpriteRepository<SpriteForm>, ISpriteFormRepository
    {
        public SpriteFormRepository(IUnitOfWork unitOfWork) : base(unitOfWork) { }

        #region Sql

        private const string SqlGetAllSpriteFormByApplicationCode = @"SELECT * FROM SpriteForms WHERE ApplicationCode=@ApplicationCode;";

        #endregion

        public List<SpriteForm> GetAllSpriteFormByApplicationCode(string applicationCode)
        {
            return _unitOfWork.Connection.Query<SpriteForm>(SqlGetAllSpriteFormByApplicationCode, new { ApplicationCode = applicationCode }, _unitOfWork.Transaction).ToList();
        }

        public async Task CommonChangeChildDatas<T>(Guid formId, string tableName, string updateFieldName, string formIdField = "FormId", bool isOrder = false)
        {
            var strSql = $"SELECT * FROM {tableName} WHERE {formIdField}=@FormId{(isOrder ? " ORDER BY `Order`" : "")};";
            var childResults = (await _unitOfWork.Connection.QueryAsync<T>(strSql, new { FormId = formId }, _unitOfWork.Transaction)).ToList();
            var strUpdateSql = $"UPDATE SpriteForms SET {updateFieldName}=@UpdateValue,Version=@Version WHERE Id=@FormId";
            string updateValue = "";
            if (childResults.Count > 0)
            {
                updateValue = JsonConvert.SerializeObject(childResults, new JsonSerializerSettings { ContractResolver = new Newtonsoft.Json.Serialization.CamelCasePropertyNamesContractResolver() });
            }
            await _unitOfWork.Connection.ExecuteAsync(strUpdateSql, new { FormId = formId, UpdateValue = updateValue, Version = Guid.NewGuid() }, _unitOfWork.Transaction);
        }

        public async Task ChangeItemRowColChildDatas(Guid formId)
        {
            var strSqlItem = $"SELECT * FROM FormItems WHERE FormId=@FormId;";
            var formItems = (await _unitOfWork.Connection.QueryAsync<FormItem>(strSqlItem, new { FormId = formId }, _unitOfWork.Transaction)).OrderBy(r=>r.Order).ToList();
            var strSqlRow = $"SELECT * FROM FormRows WHERE FormId=@FormId;";
            var formRows = (await _unitOfWork.Connection.QueryAsync<FormRow>(strSqlRow, new { FormId = formId }, _unitOfWork.Transaction)).OrderBy(r => r.Order).ToList();
            var strSqlCol = $"SELECT * FROM FormCols WHERE FormId=@FormId;";
            var formCols = (await _unitOfWork.Connection.QueryAsync<FormCol>(strSqlCol, new { FormId = formId }, _unitOfWork.Transaction)).OrderBy(r => r.Order).ToList();
            formRows.ForEach(r =>
            {
                r.Children = formCols.Where(t => t.FormRowId == r.Id).ToList();
            });
            formItems.ForEach(r =>
            {
                r.Children = formRows.Where(t => t.FormItemId == r.Id).ToList();
            });
            var strUpdateSql = $"UPDATE SpriteForms SET FormItems=@UpdateValue,Version=@Version WHERE Id=@FormId";
            string updateValue = "";
            if (formItems.Count > 0)
            {
                updateValue = JsonConvert.SerializeObject(formItems, new JsonSerializerSettings { ContractResolver = new Newtonsoft.Json.Serialization.CamelCasePropertyNamesContractResolver() });
            }
            await _unitOfWork.Connection.ExecuteAsync(strUpdateSql, new { FormId = formId, UpdateValue = updateValue, Version = Guid.NewGuid() }, _unitOfWork.Transaction);
        }

        public async Task ChangeRuleActionChildDatas(Guid formId)
        {
            var strSqlRule = $"SELECT * FROM SpriteRules WHERE BusinessId=@FormId;";
            var rules = (await _unitOfWork.Connection.QueryAsync<SpriteRule>(strSqlRule, new { FormId = formId }, _unitOfWork.Transaction)).ToList();
            var strSqlAction = $"SELECT * FROM RuleActions WHERE BusinessId=@FormId;";
            var actions = (await _unitOfWork.Connection.QueryAsync<RuleAction>(strSqlAction, new { FormId = formId }, _unitOfWork.Transaction)).OrderBy(r => r.Order).ToList();
            rules.ForEach(r =>
            {
                r.Children = actions.Where(t => t.RuleId == r.Id).ToList();
            });
            var strUpdateSql = $"UPDATE SpriteForms SET Rules=@UpdateValue,Version=@Version WHERE Id=@FormId";
            string updateValue = "";
            if (rules.Count > 0)
            {
                updateValue = JsonConvert.SerializeObject(rules, new JsonSerializerSettings { ContractResolver = new Newtonsoft.Json.Serialization.CamelCasePropertyNamesContractResolver() });
            }
            await _unitOfWork.Connection.ExecuteAsync(strUpdateSql, new { FormId = formId, UpdateValue = updateValue, Version = Guid.NewGuid() }, _unitOfWork.Transaction);
        }
    }
}
